import * as step from '@flow-step/step-toolkit'
import * as cheerio from 'cheerio'

import * as path from 'path'
import * as fsPromises from 'fs/promises'
import process from 'process'


export async function findClassFilesToFile(searchDir: string, outputFilePath: string) {

    const classFiles = await findClassFiles(searchDir)
    if (!classFiles) {
        step.error('没有找到任何class文件，请先执行Java 构建')
        process.exit(1)
    }
    await writeFile(outputFilePath, classFiles)
}

export async function createDirectory(directoryPath: string): Promise<void> {
    await fsPromises.mkdir(directoryPath, {recursive: true})
}

async function findClassFiles(dir: string, fileList: string[] = []): Promise<string[]> {
    try {
        const files = await fsPromises.readdir(dir)

        for (const file of files) {
            const fullPath = path.join(dir, file)
            const stat = await fsPromises.stat(fullPath)

            if (stat.isDirectory()) {
                await findClassFiles(fullPath, fileList)
            } else if (stat.isFile() && file.endsWith('.class')) {
                fileList.push(fullPath)
            }
        }
    } catch (error) {
        console.error(`Error reading directory ${dir}: `, error)
    }
    return fileList
}

async function writeFile(filePath: string, data: string[]): Promise<void> {
    try {
        await fsPromises.writeFile(filePath, data.join('\n'), 'utf-8')
        console.log(`Successfully wrote ${data.length} class file paths to ${filePath}`)
    } catch (error) {
        console.error(`Error writing to file ${filePath}: `, error)
    }
}

export async function deleteDirectory(dirPath: string): Promise<void> {
    try {
        const files = await fsPromises.readdir(dirPath)
        for (const file of files) {
            const currentPath = path.join(dirPath, file)
            const stat = await fsPromises.stat(currentPath)
            if (stat.isDirectory()) {
                await deleteDirectory(currentPath)
            } else {
                await fsPromises.unlink(currentPath)
            }
        }
        await fsPromises.rmdir(dirPath)
    } catch (error) {
    }
}


export async function parseReportHtml(reportHtml: string): Promise<ReportWarnings> {
    const htmlContent = await readHtmlFile(reportHtml)
    const reportWarnings = parseWarnings(htmlContent)
    return reportWarnings
}

async function readHtmlFile(filePath: string): Promise<string> {
    try {
        const data = await fsPromises.readFile(filePath, 'utf-8')
        return data
    } catch (error) {
        console.error(`Error reading file ${filePath}: `, error)
        throw error
    }
}

async function parseWarnings(htmlContent: string): Promise<ReportWarnings> {
    const $ = cheerio.load(htmlContent)

    let totalWarnings = 0
    let highWarnings = 0
    let mediumWarnings = 0
    let lowWarnings = 0

    $('tr').each((index: any, element: any) => {
        const metricText = $(element).find('td').eq(0).text().trim()

        if (metricText.includes('High Priority Warnings')) {
            const warningsCount = $(element).find('td').eq(1).text().trim()
            if (warningsCount) {
                highWarnings += parseInt(warningsCount, 10)
            }
        }
        if (metricText.includes('Medium Priority Warnings')) {
            const warningsCount = $(element).find('td').eq(1).text().trim()
            if (warningsCount) {
                mediumWarnings += parseInt(warningsCount, 10)
            }
        }
        if (metricText.includes('Low Priority Warnings')) {
            const warningsCount = $(element).find('td').eq(1).text().trim()
            if (warningsCount) {
                lowWarnings += parseInt(warningsCount, 10)
            }
        }
    })
    totalWarnings = highWarnings + mediumWarnings + lowWarnings
    const report = {} as ReportWarnings
    report.highWarnings = highWarnings
    report.totalWarnings = totalWarnings
    report.mediumWarnings = mediumWarnings
    report.lowWarnings = lowWarnings
    return report
}

export type ReportWarnings = {
    totalWarnings: number,
    highWarnings: number
    mediumWarnings: number
    lowWarnings: number

}



